#include <common.h>
#include <thread.h>
#include <scheduler.h>

unsigned int m_sched = 0;
void init_scheduler(thread *initial_th)
{
	current_thread_l = (thread_list *)kmalloc(sizeof(thread_list));
	current_thread_l->th = initial_th;
	current_thread_l->next = 0;
	ready_queue = 0;
}

void thread_is_ready(thread *th)
{
	spin(&m_sched);
	thread_list *item = (thread_list *)kmalloc(sizeof(thread_list));
	item->th = th;
	item->next = 0;
	
	if(!ready_queue)
	{
		ready_queue = item;
	} else {
		thread_list *i = ready_queue;
		while(i->next)
			i = i->next;
		i->next = item;
	}
	m_sched = 0;
}

void thread_is_first(thread *th)
{
	spin(&m_sched);
	thread_list *item = (thread_list *)kmalloc(sizeof(thread_list));
	item->th = th;
	item->next = ready_queue;
	ready_queue = item;
	m_sched = 0;
}

void thread_not_ready(thread *th)
{
	spin(&m_sched);
	thread_list *i = ready_queue;
	
	if(i->th == th)
	{
		ready_queue = i->next;
		kfree(i);
		m_sched = 0;
		return;
	}
	
	while(i->next)
	{
		if(i->next->th == th)
		{
			thread_list *temp = i->next;
			i->next = temp->next;
			kfree(temp);
		}
		i = i->next;
	}
	m_sched = 0;
}

void skip_to_thread(thread *th, registers *r)
{
	asm("cli");
	thread_is_first(current_thread); 
	thread_not_ready(th);
	switch_thread(th,r);
}

void schedule(registers *r)
{
	
	if (!ready_queue) return;
	asm("cli");
	if(current_thread->state != TH_ZOMBIE)
	{
		thread_is_ready(current_thread);
	}
	thread *t = ready_queue->th;
	thread_not_ready(t);
	switch_thread(t,r);
}
